package com.example.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.dto.UpdateMerchantInfoSimpleDTO;
import com.example.entity.dto.WechatReturnObjectDTO;
import com.example.entity.po.AuditRecord;
import com.example.entity.po.Merchant;
import com.example.entity.po.Shop;
import com.example.entity.vo.MerchantMessageMainVO;
import com.example.exception.ServiceException;
import com.example.mapper.AuditRecordMapper;
import com.example.mapper.MerchantMapper;
import com.example.mapper.ShopMapper;
import com.example.service.MerchantService;
import com.example.utils.CommonUtil;
import com.example.utils.JwtUtil;
import com.example.utils.WechatUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Zeran2023
 * @description 针对表【t_merchant】的数据库操作Service实现
 * @createDate 2024-12-24 15:29:00
 */
@Service
@Slf4j
public class MerchantServiceImpl extends ServiceImpl<MerchantMapper, Merchant> implements MerchantService {

	@Autowired
	private WechatUtil wechatUtil;

	@Autowired
	private MerchantMapper merchantMapper;

	@Autowired
	private ShopMapper shopMapper;

	@Autowired
	private AuditRecordMapper auditRecordMapper;
	@Autowired
	private CommonUtil commonUtil;

	@Override
	public void updateMerchantSimpleInfo(UpdateMerchantInfoSimpleDTO updateMerchantInfoSimpleDTO, String token) {
		if (updateMerchantInfoSimpleDTO.getAvatarFile() == null || updateMerchantInfoSimpleDTO.getNickname().trim().isEmpty()) {
			throw new ServiceException("传入不能为空");
		}

		String merchantId = JwtUtil.parseTokenId(token);

		Merchant merchant = Merchant.builder()
				.nickname(updateMerchantInfoSimpleDTO.getNickname())
				.modifyTime(LocalDateTime.now())
				.build();
		try {
			System.out.println(updateMerchantInfoSimpleDTO.getAvatarFile().getOriginalFilename());
			ReflectUtil.setFieldValue(updateMerchantInfoSimpleDTO.getAvatarFile(), "filename", "head.png");
			commonUtil.uploadFile(updateMerchantInfoSimpleDTO.getAvatarFile(), "/merchant/" + merchantId);
			System.out.println(updateMerchantInfoSimpleDTO.getAvatarFile().getOriginalFilename());

			// 将文件名更新到头像地址中
			merchant.setAddress(updateMerchantInfoSimpleDTO.getAvatarFile().getOriginalFilename());
			merchantMapper.update(merchant, new LambdaQueryWrapper<Merchant>().eq(Merchant::getMerchantId,
					merchantId));
		} catch (UtilException e) {
			log.error("业务更新异常{}", e.getMessage());
			throw new ServiceException(e.getMessage());
		}
	}


	@Override
	public MerchantMessageMainVO getMerchantInfo(String token, String queryTime) {
		Long merchantId = Long.valueOf(JwtUtil.parseTokenId(token));
		Merchant merchant = merchantMapper.selectById(merchantId);
		if (merchant == null) {
			throw new ServiceException("商家不存在");
		}
		MerchantMessageMainVO merchantMessageMainVO = MerchantMessageMainVO.builder()
				.nickname(merchant.getNickname())
				.merchantId(merchant.getMerchantId())
				.avatar(merchant.getAvatar())
				.daysRemaining(merchant.getDaysRemaining())
				.balance(merchant.getBalance())
				.build();
		Shop shop = shopMapper.selectOne(new LambdaQueryWrapper<Shop>().eq(Shop::getMerchantId, merchantId));
		if (shop == null) {
			throw new ServiceException("商家没有店铺");
		}
		Long shopId = shop.getShopId();
		// 查询待审核记录
		Long auditRecordCount = auditRecordMapper.selectCount(new LambdaQueryWrapper<AuditRecord>()
				.eq(AuditRecord::getShopId, shopId)
				.eq(AuditRecord::getStatusId, 1));
		merchantMessageMainVO.setAuditCount(auditRecordCount);
		// log.info("待审核记录{}", auditRecordCount);

		LambdaQueryWrapper<AuditRecord> queryWrapper = new LambdaQueryWrapper<>();
		// 查询店铺id对应记录的数量
		queryWrapper.eq(AuditRecord::getShopId, shopId);
		// 根据日期过滤条件计算开始时间和结束时间
		LocalDateTime startTime = null;
		LocalDateTime endTime = null;
		LocalDateTime now = LocalDateTime.now();
		switch (queryTime) {
			case "today" -> {
				startTime = LocalDateTimeUtil.beginOfDay(now); // 今天凌晨
				endTime = now; // 当前时间
			}
			case "yesterday" -> {
				startTime = LocalDateTimeUtil.beginOfDay(now.minusDays(1)); // 昨天凌晨
				endTime = LocalDateTimeUtil.endOfDay(now.minusDays(1)); // 昨天 23:59:59
			}
			case "last30day" -> {
				startTime = now.minusDays(30); // 30 天前
				endTime = now; // 当前时间
			}
			case "all" -> {
				// 不限制开始时间
				// 不限制结束时间
			}
			default -> throw new ServiceException("无效的时间过滤条件：" + queryTime);
		}

		// 设置查询条件
		if (startTime != null) {
			if (endTime != null) {
				// 如果有结束时间，使用 between
				queryWrapper.between(AuditRecord::getCreateTime, startTime, endTime);
			} else {
				// 如果没有结束时间，只限制开始时间
				queryWrapper.ge(AuditRecord::getCreateTime, startTime);
			}
		}
		queryWrapper.eq(AuditRecord::getDelFlag, 0);
		List<AuditRecord> auditRecords = auditRecordMapper.selectList(queryWrapper);

		// 计算总消费金额和有效订单数
		BigDecimal allConsume = auditRecords.stream()
				.filter(auditRecord -> auditRecord.getStatusId() == 2) // 筛选状态为2的记录
				.map(auditRecord -> BigDecimal.valueOf(auditRecord.getAuditMoney())) // 获取消费金额
				.reduce(BigDecimal.ZERO, BigDecimal::add); // 累加消费金额

		long effectiveCount = auditRecords.stream()
				.filter(auditRecord -> auditRecord.getStatusId() == 2) // 筛选状态为2的记录
				.count(); // 计算记录数

		// 设置总消费金额和总订单数
		merchantMessageMainVO.setAllConsume(allConsume);
		merchantMessageMainVO.setAllPrice(allConsume); // allPrice 和 allConsume 是相同的
		merchantMessageMainVO.setEffectiveCount(effectiveCount);

		return merchantMessageMainVO;
	}

	@Override
	public Map<String, String> login(String loginCode, String token) {
		// 如果token存在且用户在数据库，则返回新的token
		if (StrUtil.isNotBlank(token)) {
			if (JwtUtil.verifyToken(token)) {
				// 解析id
				String merchantId = JwtUtil.parseTokenId(token);
				if (Long.parseLong(merchantId) < 10000) {
					throw new ServiceException("传入token不属于商家");
				}
				String newToken = JwtUtil.generateToken(merchantId);
				return Map.of("merchantId", merchantId, "token", newToken, "isFirstLogin", "false");
			}
		}
		// 检查loginCode
		if (StrUtil.isBlank(loginCode)) {
			throw new ServiceException("loginCode不能为空");
		}
		WechatReturnObjectDTO wechatReturnObj = wechatUtil.validLoginCodeFromWechat(loginCode);
		String openid = wechatReturnObj.getOpenid();

		LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(Merchant::getOpenid, openid);
		Merchant merchant = merchantMapper.selectOne(wrapper);
		HashMap<String, String> map = new HashMap<>();
		map.put("isFirstLogin", "false");
		if (ObjectUtil.isNull(merchant)) {
			LocalDateTime now = LocalDateTime.now();
			merchant = Merchant.builder()
					.openid(wechatReturnObj.getOpenid())
					.nickname("商家" + RandomUtil.randomNumbers(6))
					.createTime(now)
					.modifyTime(now)
					.salt(RandomUtil.randomString(6))
					.build();
			merchantMapper.insert(merchant);
			map.put("isFirstLogin", "true");

			// 插入店铺信息
			Shop shop = Shop.builder()
					.shopName("随机店铺" + RandomUtil.randomNumbers(6))
					.merchantId(merchant.getMerchantId())
					.build();
			shopMapper.insert(shop);

		}
		token = JwtUtil.generateToken(merchant.getMerchantId().toString());

		map.put("merchantId", String.valueOf(merchant.getMerchantId()));
		map.put("token", token);
		return map;
	}

	@Override
	public byte[] generateWechatQRCode(String shopId) {
		return wechatUtil.generateWechatQRCode(shopId);
	}

}




